package yicr;

import yicr.geoHash.GeoHash;
import yicr.geoHash.UtilGeoHash;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <h3>Title:</h3>
 * <p>
 *
 * <h3>Description</h3>
 * <p>
 *
 * <h3>Author</h3>
 * <p>
 * Lin Shao
 * <h3>Update Time</h3>
 * <p>2021-10-24 0:10
 *
 * @author Lin Shao
 * @version 1.0
 */
public class Calculation {
    static int longitudeIndex=-1;
    static int latitudeIndex=-1;

    //lineList保存csv文件读入的内容，以string每行形式保存
    public static List<String> importCellData(String csvFilePath, Form form){
        List<String> lineList=new ArrayList<>();


        File csvFile=new File(csvFilePath);
        int i=0;
        try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(csvFilePath),"gbk"))) {

            String line = "";


            while ((line = br.readLine()) != null) {
                if(i==0){
                    i++;
                    String[] array=line.split(",");
                    for (int j = 0; j < array.length; j++) {
                        if(array[j].equalsIgnoreCase(form.getLatitudeColumnName())){
                            latitudeIndex=j;
                        }
                        if(array[j].equalsIgnoreCase(form.getLongitudeColumnName())){
                            longitudeIndex=j;
                        }
                    }
                    if(latitudeIndex == -1 || longitudeIndex == -1){
                        throw new RuntimeException("经度或纬度 列明指定错误.");
                    }
                    lineList.add(line+",geohash");
                    continue;
                }

                lineList.add(line);
                i++;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return lineList;
    }

    //计算平均覆盖半径，下倾角
    //算法大概
    // 1. 对maincell 找出3个距离最近得基站，需满足 maincell 方向角与三个距离最近基站夹角小于60.
    // 2. 根据3个基站覆盖距离，算出覆盖半径 覆盖距离* MainCell.Height(MainCell.Height+NeighbourCell.Height),并考虑基站类型下的最大覆盖半径;
    // 3. 取得平均覆盖半径，对3个覆盖半径，加权平均 R1*0.7+R2*0.2+R3*0.1
    // 4. 根据atan(MaiCell.Height/平均覆盖半径)，初算出下倾角，再根据垂直半功率角,15度门限，过滤一次
    // 5. 搞定
    static public void calDowntilt(List<Cell> cellList, Form form){
        //init distancesWithNeighbour of cell
        double marginDistance=1000000d;
        for (Cell cell : cellList) {
            List<RelationWithNeighbour> neighbourList=new ArrayList<>();
            cell.setMarginDistance(marginDistance);
            cell.setNeighbourList(neighbourList);
            for (int i = 0; i < 3; i++) {
                Cell cellT=new Cell();
                cellT.setSiteHeight(0);
                cellT.setCellName("null");
                cellT.setSiteName("null");
                cellT.setRowId(150);
               RelationWithNeighbour distanceWithNeighbour=new RelationWithNeighbour(cell,cellT,marginDistance);
               neighbourList.add(distanceWithNeighbour);
            }
        }


        int size=cellList.size();
        for (int i = 0; i < size; i++) {
            Cell mainCell=cellList.get(i);
            List<RelationWithNeighbour> neighbourList=mainCell.getNeighbourList();
            for(int j=1; j< size; j++){
                Cell comparedCell=cellList.get(j);

                if(i==j || mainCell.getSiteName().equalsIgnoreCase(comparedCell.getSiteName()) ){
                    continue;
                }

                double distance=GisFunction.distance(mainCell.getLongitude(),mainCell.getLatitude(),comparedCell.getLongitude(),comparedCell.getLatitude());

                double angle=GisFunction.cellsAngel(mainCell.getLongitude(),mainCell.getLatitude(),comparedCell.getLongitude(),comparedCell.getLatitude());

                double cellAngle=(int)mainCell.getAngel()%360;

                double differOfAngle= Math.abs(cellAngle-angle);

                // 最近的小区是否是同一个站
                boolean whetherRepeat=false;

                if(differOfAngle <= 60){
                    marginDistance=mainCell.getMarginDistance();
                    if(distance<marginDistance){

                        for (RelationWithNeighbour relationWithNeighbour : neighbourList) {
                            if(relationWithNeighbour.getNeighbourCell().getSiteName().equals(comparedCell.getSiteName())){
                                whetherRepeat=true;
                                break;
                            }
                        }
                        if(!whetherRepeat){
                            neighbourList.add(new RelationWithNeighbour(mainCell,comparedCell,distance));
                            Collections.sort(neighbourList);
                            neighbourList=neighbourList.subList(0,3);
                            //System.out.println(neighbourList.size());
                            mainCell.setMarginDistance(neighbourList.get(2).getDistance());
                        }

                    }
                }



            }

            double maxCoverRange=0;
            if(mainCell.getRegionCategory().equalsIgnoreCase("城区")){
                maxCoverRange=form.getCityCoverRange();
            }else  if(mainCell.getRegionCategory().equalsIgnoreCase("郊区")){
                maxCoverRange=form.getSuburbCoverRange();
            }else {
                maxCoverRange=form.getRuralCoverRange();
            }


            String neighbourlog=(i+1)+"  =  ";

            for (RelationWithNeighbour relationWithNeighbour : neighbourList) {
                //System.out.println(relationWithNeighbour);

                double coverRadius=relationWithNeighbour.getDistance()*mainCell.getSiteHeight()/(mainCell.getSiteHeight()+relationWithNeighbour.getNeighbourCell().getSiteHeight());
                if(coverRadius>maxCoverRange){
                    coverRadius=maxCoverRange;
                }

                relationWithNeighbour.setCoverRadius(coverRadius);

                Cell neighbourCell=relationWithNeighbour.getNeighbourCell();

                neighbourlog+=neighbourCell.getRowId()+" , ";

               /* for (int j = 0; j < cellList.size(); j++) {
                    if(cellList.get(j).getCellName().equalsIgnoreCase(neighbourCell.getCellName())){
                        neighbourlog+=j + " , ";
                    }
                    if(neighbourCell.getCellName().equals("null")){
                        neighbourlog+=150+ " , ";
                    }
                }*/

            }

            //System.out.println(neighbourlog);

            double averageCoverRadius=neighbourList.get(0).getCoverRadius()*0.8+neighbourList.get(1).getCoverRadius()*0.15+neighbourList.get(2).getCoverRadius()*0.05;

            mainCell.setAverageCoverRadius(averageCoverRadius);

            double newDowntitle= Math.atan(mainCell.getSiteHeight()/mainCell.getAverageCoverRadius())/ Math.PI*180;

            if(newDowntitle<mainCell.getVerticalBeam()/2){
                newDowntitle=mainCell.getVerticalBeam()/2;
            }else if(newDowntitle>15){
                newDowntitle=15;
            }

            mainCell.setNewDowntilt(newDowntitle);
        }

    }


    static public void exportCsv2(List<String> lineList,String outputFilePath) throws Exception {
        try(FileOutputStream out=new FileOutputStream(outputFilePath);
            OutputStreamWriter osw=new OutputStreamWriter(out,"GB2312");
            BufferedWriter bw =new BufferedWriter(osw,50*1024*1024)){
            if(lineList!=null && !lineList.isEmpty()){
                for (String s : lineList) {
                    bw.append(s).append("\r").append("\n");;
                }

                }
            }
    }

    static public void exportCsv(List<Cell> cellList, List<String> lineList, String outputFilePath){
        File outFile=new File(outputFilePath);

        String csvHead="地市,小区名称,基站名称,区域类型,小区号,经度,纬度,站高,方向角,天线垂直波束,原下倾角,取定覆盖半径 (m),调整后下倾角,下倾角差异";

        boolean isSucess=false;
        try(FileOutputStream out=new FileOutputStream(outFile);
            OutputStreamWriter osw=new OutputStreamWriter(out,"GB2312");
            BufferedWriter bw =new BufferedWriter(osw,50*1024*1024)){
            if(cellList!=null && !cellList.isEmpty()){
                String headLine=lineList.get(0)+",取定覆盖半径(m),调整后下倾角\r\n";
                //headLine=new String(headLine.getBytes(),Charset.forName("UTF-8"));
                bw.append(headLine);
                for (int i = 0; i < cellList.size(); i++) {
                    String line;
                    Cell cell=cellList.get(i);
                    line=lineList.get(i+1)+","+ Math.round(cell.getAverageCoverRadius())+","+ Math.round(cell.getNewDowntilt())+"\n";
                    bw.append(line);
                }
            }
            isSucess=true;
        }catch (Exception e){
            isSucess=false;
        }

    }

    public static List<String> calGeoHash(List<String> lineList,Form form ){
        int geohashBit=form.getGeohashBit();
        List<String> resultLineList=new ArrayList<>(lineList.size());
        GeoHash geoHash=UtilGeoHash.create(geohashBit);

        for (int i = 0; i < lineList.size(); i++) {
            String line = lineList.get(i);
            if (i == 0) {
                resultLineList.add(line);
                continue;
            }

            String[] array = line.split(",");
            System.out.println(i);
            double latitude = Double.parseDouble(array[latitudeIndex]);
            double longitude = Double.parseDouble(array[longitudeIndex]);
            String geohashValue=geoHash.encode(latitude,longitude);
            line=line+","+geohashValue;
            resultLineList.add(line);
        }

        return resultLineList;
    }

    public static void main(String[] args) {
        String csvFilePath="Z:\\GS_Dir_Zdisk\\GS#i3#Work\\2021SJY\\软课题\\AD\\import.csv";
        String outputCsvFilePath="Z:\\GS_Dir_Zdisk\\GS#i3#Work\\2021SJY\\软课题\\AD\\output.csv";
        List<String> lineList=new ArrayList();


        //List<String> cellList=importCellData(csvFilePath,lineList);

        Form form=new Form();
        form.setCityCoverRange(400);
        form.setSuburbCoverRange(700);
        form.setRuralCoverRange(8000);

        //calDowntilt(cellList,form);

        //exportCsv(cellList,lineList,outputCsvFilePath);

    }
}
